#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
报告模板管理器模块
负责管理和加载分析报告模板
"""

import os
import json
import logging
import re
import threading
from typing import Dict, Any, List, Optional, Union
from pathlib import Path
from datetime import datetime

# 设置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
)
logger = logging.getLogger(__name__)


class TemplateError(Exception):
    """
    模板相关异常
    """
    pass


class ReportTemplateManager:
    """
    报告模板管理器
    提供模板的加载、缓存、解析和渲染功能
    """
    
    def __init__(self, 
                 templates_dir: str = None,
                 default_template: str = "standard"):
        """
        初始化报告模板管理器
        
        Args:
            templates_dir: 模板目录
            default_template: 默认模板名称
        """
        # 设置模板目录
        if templates_dir:
            self._templates_dir = templates_dir
        else:
            # 默认模板目录
            self._templates_dir = os.path.join(
                os.path.dirname(os.path.dirname(os.path.dirname(__file__))),
                "data", "templates"
            )
        
        # 默认模板
        self._default_template = default_template
        
        # 线程锁
        self._lock = threading.RLock()
        
        # 模板缓存
        self._templates = {}
        
        # 确保模板目录存在
        os.makedirs(self._templates_dir, exist_ok=True)
        
        # 初始化模板
        self._init_default_templates()
        
        # 加载模板
        self._load_templates()
        
        logger.info(f"报告模板管理器初始化完成，模板目录: {self._templates_dir}")
    
    def _init_default_templates(self):
        """
        初始化默认模板
        """
        # 标准报告模板
        standard_template = {
            "name": "standard",
            "description": "标准分析报告模板",
            "version": "1.0.0",
            "created_at": datetime.now().isoformat(),
            "sections": [
                {
                    "id": "header",
                    "title": "视频内容分析报告",
                    "content": "# 视频内容分析报告\n\n## 基本信息\n- **报告生成时间**: {{ report_time }}\n- **视频ID**: {{ video_id }}\n- **视频标题**: {{ video_title }}\n- **分析工具**: {{ analysis_tool }}\n\n## 整体分析概述\n{{ overall_summary }}\n"
                },
                {
                    "id": "category_analysis",
                    "title": "编码类目分析",
                    "content": '## 编码类目分析\n\n{% for category, data in category_analysis.items() %}\n### {{ category }}\n- **判定结果**: {{ data.result }}\n- **置信度**: {{ (data.confidence * 100) | round(2) }}%\n- **分析依据**: {{ data.reasoning }}\n{% if data.keywords %}- **相关关键词**: {{ \', \'.join(data.keywords) }}{% endif %}\n\n{% endfor %}\n'
                },
                {
                    "id": "visual_features",
                    "title": "视觉特征分析",
                    "content": '## 视觉特征分析\n\n{% if visual_features.scene_description %}\n### 场景描述\n{{ visual_features.scene_description }}\n\n{% endif %}\n{% if visual_features.key_elements %}\n### 关键元素\n{% for element in visual_features.key_elements %}\n- {{ element.name }} (置信度: {{ (element.confidence * 100) | round(2) }}%)\n{% endfor %}\n\n{% endif %}\n{% if visual_features.colors %}\n### 色彩分析\n主要色彩: {{ \', \'.join(visual_features.colors) }}\n\n{% endif %}\n{% if visual_features.images_count %}\n### 图片统计\n- 关键帧数量: {{ visual_features.images_count }}\n- 有效分析帧: {{ visual_features.valid_frames_count }}\n\n{% endif %}\n'
                },
                {
                    "id": "text_features",
                    "title": "文本特征分析",
                    "content": '## 文本特征分析\n\n{% if text_features.sentiment %}\n### 情感分析\n- **情感倾向**: {{ text_features.sentiment.label }}\n- **情感强度**: {{ (text_features.sentiment.confidence * 100) | round(2) }}%\n\n{% endif %}\n{% if text_features.keywords %}\n### 关键词提取\n{% for keyword, weight in text_features.keywords[:10] %}\n- {{ keyword }} (权重: {{ weight | round(2) }})\n{% endfor %}\n\n{% endif %}\n{% if text_features.topics %}\n### 主题分析\n{% for topic in text_features.topics[:5] %}\n- **主题**: {{ topic.topic }}\n  - 相关关键词: {{ \', \'.join(topic.keywords[:3]) }}\n  - 相关度: {{ (topic.relevance * 100) | round(2) }}%\n{% endfor %}\n\n{% endif %}\n{% if text_features.summary %}\n### 内容摘要\n{{ text_features.summary }}\n\n{% endif %}\n'
                },
                {
                    "id": "conclusion",
                    "title": "总结与建议",
                    "content": "## 总结与建议\n\n### 内容分类总结\n{{ content_summary }}\n\n### 受众建议\n{{ audience_suggestions }}\n\n### 内容优化建议\n{{ optimization_suggestions }}\n\n---\n\n*本报告由AI大模型视频编码分析系统自动生成*\n"
                }
            ],
            "output_formats": ["markdown", "html", "txt"]
        }
        
        # 简洁报告模板
        concise_template = {
            "name": "concise",
            "description": "简洁分析报告模板",
            "version": "1.0.0",
            "created_at": datetime.now().isoformat(),
            "sections": [
                {
                    "id": "header",
                    "title": "视频分析摘要",
                    "content": "# 视频分析摘要\n\n- **生成时间**: {{ report_time }}\n- **视频ID**: {{ video_id }}\n\n"
                },
                {
                    "id": "category_results",
                    "title": "编码类目结果",
                    "content": '## 编码类目结果\n\n| 类目 | 结果 | 置信度 |\n|------|------|--------|\n{% for category, data in category_analysis.items() %}\n| {{ category }} | {{ data.result }} | {{ (data.confidence * 100) | round(2) }}% |\n{% endfor %}\n\n'
                },
                {
                    "id": "key_findings",
                    "title": "关键发现",
                    "content": "## 关键发现\n\n{% if text_features.keywords %}\n### 核心关键词\n{{ ', '.join([k[0] for k in text_features.keywords[:8]]) }}\n\n{% endif %}\n{% if text_features.sentiment %}\n### 情感倾向\n{{ text_features.sentiment.label }}\n\n{% endif %}\n{% if visual_features.key_elements %}\n### 视觉关键元素\n{{ ', '.join([e.name for e in visual_features.key_elements[:5]]) }}\n\n{% endif %}\n"
                }
            ],
            "output_formats": ["markdown", "txt"]
        }
        
        # HTML报告模板
        html_template = {
            "name": "html",
            "description": "HTML格式报告模板",
            "version": "1.0.0",
            "created_at": datetime.now().isoformat(),
            "sections": [
                {
                    "id": "header",
                    "title": "HTML报告头部",
                    "content": '<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n    <meta charset="UTF-8">\n    <meta name="viewport" content="width=device-width, initial-scale=1.0">\n    <title>视频内容分析报告 - {{ video_id }}</title>\n    <style>\n        body { font-family: Arial, \'Microsoft YaHei\', sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }\n        h1, h2, h3 { color: #2c3e50; }\n        .header { background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 30px; }\n        .info-card { background: #fff; border: 1px solid #e0e0e0; border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n        .category-item { margin-bottom: 15px; padding-bottom: 15px; border-bottom: 1px dashed #e0e0e0; }\n        .category-item:last-child { border-bottom: none; }\n        .confidence-high { color: #27ae60; }\n        .confidence-medium { color: #f39c12; }\n        .confidence-low { color: #e74c3c; }\n        .footer { margin-top: 40px; padding-top: 20px; border-top: 1px solid #e0e0e0; text-align: center; color: #7f8c8d; font-size: 14px; }\n        table { width: 100%; border-collapse: collapse; margin: 20px 0; }\n        th, td { border: 1px solid #ddd; padding: 8px 12px; text-align: left; }\n        th { background-color: #f2f2f2; }\n    </style>\n</head>\n<body>\n    <div class="header">\n        <h1>视频内容分析报告</h1>\n        <p><strong>报告生成时间:</strong> {{ report_time }}</p>\n        <p><strong>视频ID:</strong> {{ video_id }}</p>\n        {% if video_title %}<p><strong>视频标题:</strong> {{ video_title }}</p>{% endif %}\n    </div>\n\n'
                },
                {
                    "id": "summary",
                    "title": "分析概述",
                    "content": '    <div class="info-card">\n        <h2>分析概述</h2>\n        <p>{{ overall_summary }}</p>\n    </div>\n\n'
                },
                {
                    "id": "categories",
                    "title": "编码类目分析",
                    "content": '    <div class="info-card">\n        <h2>编码类目分析</h2>\n        {% for category, data in category_analysis.items() %}\n        <div class="category-item">\n            <h3>{{ category }}</h3>\n            <p><strong>判定结果:</strong> {{ data.result }}</p>\n            <p><strong>置信度:</strong> <span class="confidence-{{ \'high\' if data.confidence >= 0.8 else \'medium\' if data.confidence >= 0.6 else \'low\' }}">{{ (data.confidence * 100) | round(2) }}%</span></p>\n            <p><strong>分析依据:</strong> {{ data.reasoning }}</p>\n            {% if data.keywords %}<p><strong>相关关键词:</strong> {{ \', \'.join(data.keywords) }}</p>{% endif %}\n        </div>\n        {% endfor %}\n    </div>\n\n'
                },
                {
                    "id": "visual",
                    "title": "视觉分析",
                    "content": '    <div class="info-card">\n        <h2>视觉特征分析</h2>\n        {% if visual_features.scene_description %}<p><strong>场景描述:</strong> {{ visual_features.scene_description }}</p>{% endif %}\n        \n        {% if visual_features.key_elements %}<h3>关键元素</h3>\n        <table>\n            <thead>\n                <tr><th>元素名称</th><th>置信度</th></tr>\n            </thead>\n            <tbody>\n            {% for element in visual_features.key_elements %}\n                <tr>\n                    <td>{{ element.name }}</td>\n                    <td>{{ (element.confidence * 100) | round(2) }}%</td>\n                </tr>\n            {% endfor %}\n            </tbody>\n        </table>\n        {% endif %}\n    </div>\n\n'
                },
                {
                    "id": "footer",
                    "title": "报告尾部",
                    "content": '    <div class="footer">\n        <p>本报告由AI大模型视频编码分析系统自动生成</p>\n    </div>\n</body>\n</html>'
                }
            ],
            "output_formats": ["html"]
        }
        
        # 保存默认模板
        self._save_template(standard_template)
        self._save_template(concise_template)
        self._save_template(html_template)
        
        logger.info("默认模板初始化完成")
    
    def _save_template(self, template: Dict[str, Any]):
        """
        保存模板到文件
        
        Args:
            template: 模板数据
        """
        try:
            template_name = template.get("name")
            if not template_name:
                raise TemplateError("模板名称不能为空")
            
            template_file = os.path.join(self._templates_dir, f"{template_name}.json")
            
            # 确保有版本和时间戳
            if "version" not in template:
                template["version"] = "1.0.0"
            if "created_at" not in template:
                template["created_at"] = datetime.now().isoformat()
            template["updated_at"] = datetime.now().isoformat()
            
            # 保存模板
            with open(template_file, 'w', encoding='utf-8') as f:
                json.dump(template, f, ensure_ascii=False, indent=2)
            
            logger.debug(f"模板保存成功: {template_name}")
            
        except Exception as e:
            logger.error(f"保存模板失败: {str(e)}")
            raise TemplateError(f"保存模板失败: {str(e)}")
    
    def _load_templates(self):
        """
        加载所有模板
        """
        try:
            if not os.path.exists(self._templates_dir):
                logger.warning(f"模板目录不存在: {self._templates_dir}")
                return
            
            # 遍历目录中的JSON文件
            for filename in os.listdir(self._templates_dir):
                if filename.endswith('.json'):
                    template_path = os.path.join(self._templates_dir, filename)
                    try:
                        with open(template_path, 'r', encoding='utf-8') as f:
                            template = json.load(f)
                            template_name = template.get("name", filename[:-5])
                            self._templates[template_name] = template
                            logger.debug(f"加载模板: {template_name}")
                    except Exception as e:
                        logger.error(f"加载模板文件 {filename} 失败: {str(e)}")
            
            logger.info(f"成功加载 {len(self._templates)} 个模板")
            
        except Exception as e:
            logger.error(f"加载模板失败: {str(e)}")
    
    def get_template(self, template_name: str = None) -> Dict[str, Any]:
        """
        获取指定模板
        
        Args:
            template_name: 模板名称
            
        Returns:
            Dict[str, Any]: 模板数据
            
        Raises:
            TemplateError: 模板不存在时抛出
        """
        with self._lock:
            # 如果未指定，使用默认模板
            if not template_name:
                template_name = self._default_template
            
            # 检查模板是否存在
            if template_name not in self._templates:
                # 尝试重新加载
                self._load_templates()
                
                # 再次检查
                if template_name not in self._templates:
                    raise TemplateError(f"模板不存在: {template_name}")
            
            return self._templates[template_name].copy()
    
    def list_templates(self) -> List[Dict[str, Any]]:
        """
        列出所有可用模板
        
        Returns:
            List[Dict[str, Any]]: 模板列表
        """
        with self._lock:
            # 确保模板是最新的
            self._load_templates()
            
            # 返回模板元数据
            templates_info = []
            for template_name, template in self._templates.items():
                info = {
                    "name": template_name,
                    "description": template.get("description", ""),
                    "version": template.get("version", "1.0.0"),
                    "sections_count": len(template.get("sections", [])),
                    "output_formats": template.get("output_formats", []),
                    "updated_at": template.get("updated_at", "")
                }
                templates_info.append(info)
            
            return templates_info
    
    def create_template(self, 
                       template_name: str,
                       description: str,
                       sections: List[Dict[str, Any]],
                       output_formats: List[str] = None) -> bool:
        """
        创建新模板
        
        Args:
            template_name: 模板名称
            description: 模板描述
            sections: 模板章节列表
            output_formats: 支持的输出格式
            
        Returns:
            bool: 是否创建成功
        """
        try:
            with self._lock:
                # 检查模板名称是否已存在
                if template_name in self._templates:
                    raise TemplateError(f"模板已存在: {template_name}")
                
                # 验证章节格式
                for section in sections:
                    if "id" not in section or "content" not in section:
                        raise TemplateError("章节缺少必要字段: id 或 content")
                
                # 创建模板
                template = {
                    "name": template_name,
                    "description": description,
                    "version": "1.0.0",
                    "created_at": datetime.now().isoformat(),
                    "updated_at": datetime.now().isoformat(),
                    "sections": sections,
                    "output_formats": output_formats or ["markdown", "txt"]
                }
                
                # 保存模板
                self._save_template(template)
                
                # 更新缓存
                self._templates[template_name] = template
                
                logger.info(f"模板创建成功: {template_name}")
                return True
                
        except Exception as e:
            logger.error(f"创建模板失败: {str(e)}")
            raise TemplateError(f"创建模板失败: {str(e)}")
    
    def update_template(self, 
                       template_name: str,
                       description: str = None,
                       sections: List[Dict[str, Any]] = None,
                       output_formats: List[str] = None) -> bool:
        """
        更新模板
        
        Args:
            template_name: 模板名称
            description: 模板描述
            sections: 模板章节列表
            output_formats: 支持的输出格式
            
        Returns:
            bool: 是否更新成功
        """
        try:
            with self._lock:
                # 检查模板是否存在
                if template_name not in self._templates:
                    raise TemplateError(f"模板不存在: {template_name}")
                
                # 获取现有模板
                template = self._templates[template_name].copy()
                
                # 更新字段
                if description is not None:
                    template["description"] = description
                if sections is not None:
                    # 验证章节格式
                    for section in sections:
                        if "id" not in section or "content" not in section:
                            raise TemplateError("章节缺少必要字段: id 或 content")
                    template["sections"] = sections
                if output_formats is not None:
                    template["output_formats"] = output_formats
                
                # 更新时间戳
                template["updated_at"] = datetime.now().isoformat()
                
                # 保存更新后的模板
                self._save_template(template)
                
                # 更新缓存
                self._templates[template_name] = template
                
                logger.info(f"模板更新成功: {template_name}")
                return True
                
        except Exception as e:
            logger.error(f"更新模板失败: {str(e)}")
            raise TemplateError(f"更新模板失败: {str(e)}")
    
    def delete_template(self, template_name: str) -> bool:
        """
        删除模板
        
        Args:
            template_name: 模板名称
            
        Returns:
            bool: 是否删除成功
        """
        try:
            with self._lock:
                # 不允许删除默认模板
                if template_name == self._default_template:
                    raise TemplateError("不能删除默认模板")
                
                # 检查模板是否存在
                if template_name not in self._templates:
                    raise TemplateError(f"模板不存在: {template_name}")
                
                # 删除模板文件
                template_file = os.path.join(self._templates_dir, f"{template_name}.json")
                if os.path.exists(template_file):
                    os.remove(template_file)
                
                # 从缓存中移除
                del self._templates[template_name]
                
                logger.info(f"模板删除成功: {template_name}")
                return True
                
        except Exception as e:
            logger.error(f"删除模板失败: {str(e)}")
            raise TemplateError(f"删除模板失败: {str(e)}")
    
    def validate_template(self, template: Dict[str, Any]) -> Dict[str, Any]:
        """
        验证模板格式
        
        Args:
            template: 模板数据
            
        Returns:
            Dict[str, Any]: 验证结果 {"valid": bool, "errors": []}
        """
        errors = []
        
        # 检查必要字段
        required_fields = ["name", "sections"]
        for field in required_fields:
            if field not in template:
                errors.append(f"缺少必要字段: {field}")
        
        # 验证名称
        if "name" in template and not re.match(r'^[a-zA-Z0-9_\-]+$', template["name"]):
            errors.append("模板名称只能包含字母、数字、下划线和连字符")
        
        # 验证章节
        if "sections" in template:
            if not isinstance(template["sections"], list):
                errors.append("sections必须是列表类型")
            else:
                section_ids = set()
                for idx, section in enumerate(template["sections"]):
                    if not isinstance(section, dict):
                        errors.append(f"章节 {idx} 必须是字典类型")
                        continue
                    
                    # 检查章节必要字段
                    if "id" not in section:
                        errors.append(f"章节 {idx} 缺少id字段")
                    elif section["id"] in section_ids:
                        errors.append(f"章节ID重复: {section['id']}")
                    else:
                        section_ids.add(section["id"])
                    
                    if "content" not in section:
                        errors.append(f"章节 {idx} 缺少content字段")
                    elif not section["content"]:
                        errors.append(f"章节 {idx} 的content不能为空")
        
        # 验证输出格式
        if "output_formats" in template:
            valid_formats = ["markdown", "html", "txt", "pdf", "docx"]
            for fmt in template["output_formats"]:
                if fmt not in valid_formats:
                    errors.append(f"不支持的输出格式: {fmt}")
        
        return {
            "valid": len(errors) == 0,
            "errors": errors
        }
    
    def extract_template_variables(self, template_name: str) -> List[str]:
        """
        提取模板中的变量
        
        Args:
            template_name: 模板名称
            
        Returns:
            List[str]: 变量列表
        """
        try:
            template = self.get_template(template_name)
            variables = set()
            
            # 使用正则表达式提取 {{ variable }} 格式的变量
            pattern = r'\{\{\s*([^\{\}\s]+)\s*\}\}'
            
            for section in template.get("sections", []):
                content = section.get("content", "")
                matches = re.findall(pattern, content)
                variables.update(matches)
            
            return sorted(list(variables))
            
        except Exception as e:
            logger.error(f"提取模板变量失败: {str(e)}")
            return []
    
    def get_default_template_name(self) -> str:
        """
        获取默认模板名称
        
        Returns:
            str: 默认模板名称
        """
        return self._default_template
    
    def set_default_template(self, template_name: str) -> bool:
        """
        设置默认模板
        
        Args:
            template_name: 模板名称
            
        Returns:
            bool: 是否设置成功
        """
        try:
            with self._lock:
                # 检查模板是否存在
                if template_name not in self._templates:
                    # 尝试重新加载
                    self._load_templates()
                    
                    if template_name not in self._templates:
                        raise TemplateError(f"模板不存在: {template_name}")
                
                # 设置默认模板
                self._default_template = template_name
                logger.info(f"默认模板已设置为: {template_name}")
                return True
                
        except Exception as e:
            logger.error(f"设置默认模板失败: {str(e)}")
            raise TemplateError(f"设置默认模板失败: {str(e)}")


# 使用示例
if __name__ == '__main__':
    try:
        print("报告模板管理器初始化中...")
        
        # 创建实例
        manager = ReportTemplateManager()
        
        # 列出所有模板
        templates = manager.list_templates()
        print("\n可用模板列表:")
        for template in templates:
            print(f"- {template['name']}: {template['description']}")
            print(f"  章节数: {template['sections_count']}, 格式: {', '.join(template['output_formats'])}")
        
        # 提取模板变量
        print("\n标准模板变量:")
        variables = manager.extract_template_variables("standard")
        print(f"  变量数量: {len(variables)}")
        print(f"  变量列表: {', '.join(variables)}")
        
        print("\n报告模板管理器初始化成功!")
        
    except Exception as e:
        print(f"初始化失败: {str(e)}")